package cn.kuporo.seckill.goods.domain.service.impl;

import cn.kuporo.seckill.common.constants.MQConstants;
import cn.kuporo.seckill.common.exception.ErrorCode;
import cn.kuporo.seckill.common.exception.SeckillException;
import cn.kuporo.seckill.common.model.enums.SeckillGoodsStatus;
import cn.kuporo.seckill.goods.domain.event.SeckillGoodsEvent;
import cn.kuporo.seckill.goods.domain.model.SeckillGoods;
import cn.kuporo.seckill.goods.domain.repository.SeckillGoodsRepository;
import cn.kuporo.seckill.goods.domain.service.SeckillGoodsDomainService;
import cn.kuporo.seckill.mq.MessageSenderService;
import com.alibaba.fastjson.JSON;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author: kuporo
 * @since: 2025/7/9
 * @description: 领域层服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SeckillGoodsDomainServiceImpl implements SeckillGoodsDomainService {
    private final SeckillGoodsRepository seckillGoodsRepository;
    private final MessageSenderService messageSenderService;


    @Value("${message.mq.type}")
    private String mqType;

    @Override
    public void saveSeckillGoods(SeckillGoods seckillGoods) {
        log.info("goodsPublish|发布秒杀商品|{}", JSON.toJSON(seckillGoods));
        seckillGoodsRepository.saveSeckillGoods(seckillGoods);
        log.info("goodsPublish|秒杀商品已经发布|商品id:{}", seckillGoods.getId());
        SeckillGoodsEvent seckillGoodsEvent = new SeckillGoodsEvent(seckillGoods.getId(), seckillGoods.getActivityId(), SeckillGoodsStatus.PUBLISHED.getCode(),this.getTopicEvent());
        messageSenderService.send(seckillGoodsEvent);
        log.info("goodsPublish|秒杀商品事件已经发布|商品id:{}", seckillGoods.getId());
    }

    /**
     * 获取主题事件
     */
    private String getTopicEvent() {
        return MQConstants.TOPIC_EVENT_ROCKETMQ_GOODS;

    }

    @Override
    public SeckillGoods getSeckillGoodsId(Long id) {
        return seckillGoodsRepository.getSeckillGoodsId(id);
    }

    @Override
    public List<SeckillGoods> getSeckillGoodsByActivityId(Long activityId) {
        return seckillGoodsRepository.getSeckillGoodsByActivityId(activityId);
    }

    @Override
    public void updateStatus(Long id, Integer status) {
        log.info("goodsPublish|更新秒杀商品状态|商品id:{},状态:{}", id, status);
        SeckillGoods seckillGoods = seckillGoodsRepository.getSeckillGoodsId(id);
        if (seckillGoods == null){
            throw new SeckillException(ErrorCode.GOODS_NOT_EXISTS);
        }
        //更新状态状态
        seckillGoodsRepository.updateStatus(id, status);
        log.info("goodsPublish|秒杀商品状态已经更新|商品id:{},状态:{}", id, status);
        SeckillGoodsEvent seckillGoodsEvent = new SeckillGoodsEvent(seckillGoods.getId(), seckillGoods.getActivityId(), status, this.getTopicEvent());
        messageSenderService.send(seckillGoodsEvent);
        log.info("goodsPublish|秒杀商品事件已经发布|商品id:{}", seckillGoodsEvent.getId());
    }

    @Override
    public boolean updateAvailableStock(Integer count, Long id) {
        log.info("goodsPublish|更新秒杀商品库存|商品id:{}", id);
        if (count == null || count <= 0 || id == null){
            throw new SeckillException(ErrorCode.PARAMS_INVALID);
        }
        SeckillGoods seckillGoods = seckillGoodsRepository.getSeckillGoodsId(id);
        if (seckillGoods == null){
            throw new SeckillException(ErrorCode.GOODS_NOT_EXISTS);
        }
        boolean isUpdate = seckillGoodsRepository.updateAvailableStock(count, id) > 0;
        if (isUpdate){
            log.info("goodsPublish|秒杀商品库存已经更新|商品id:{}", id);
            SeckillGoodsEvent seckillGoodsEvent = new SeckillGoodsEvent(seckillGoods.getId(), seckillGoods.getActivityId(), seckillGoods.getStatus(),getTopicEvent());
            messageSenderService.send(seckillGoodsEvent);
            log.info("goodsPublish|秒杀商品库存事件已经发布|商品id:{}", id);
        }else {
            log.info("goodsPublish|秒杀商品库存未更新|商品id:{}", id);
        }
        return isUpdate;

    }

    @Override
    public Integer getAvailableStockById(Long id) {
        return seckillGoodsRepository.getAvailableStockById(id);
    }

    @Override
    public boolean updateDbAvailableStock(Integer count, Long id) {
        log.info("goodsPublish|更新秒杀商品库存|{}", id);
        if (count == null || count <= 0 || id == null){
            throw new SeckillException(ErrorCode.PARAMS_INVALID);
        }
        return seckillGoodsRepository.updateAvailableStock(count, id) > 0;
    }
}
